﻿/// ##############################################################################
/// 
/// Original Author         : Nick Hoggard (nick@silvercode.co.nz)
/// 
/// ##############################################################################
/// License and Copywrite information
/// 
/// Copyright (c) 2010, Nick Hoggard (nick@silvercode.co.nz)
/// All rights reserved.
/// 
/// Redistribution and use in source and binary forms, with or without
/// modification, are permitted provided that the following conditions are met:
///     * Redistributions of source code must retain the above copyright
///       notice, this list of conditions and the following disclaimer.
///     * Redistributions in binary form must reproduce the above copyright
///       notice, this list of conditions and the following disclaimer in the
///       documentation and/or other materials provided with the distribution.
///     * Neither the name of the copywrite holder nor the names of its contributors 
///       may be used to endorse or promote products derived from this software 
///       without specific prior written permission.
/// 
/// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
/// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
/// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
/// DISCLAIMED. IN NO EVENT SHALL Nick Hoggard BE LIABLE FOR ANY
/// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
/// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
/// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
/// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
/// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
/// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/// ##############################################################################

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Microsoft.TeamFoundation.Client;
using System.Net;
using Microsoft.TeamFoundation.WorkItemTracking.Client;
using TimeSheetControl.ObjectModel;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.TeamFoundation;
using EnvDTE80;
using System.Runtime.InteropServices;
using Microsoft.VisualStudio.TeamFoundation.WorkItemTracking;

namespace NickHoggard.TimeSheetControl_Reports_VSPackage
{
    /// <summary>
    /// Interaction logic for MyControl.xaml
    /// </summary>
    public partial class TFSTimesheetReportControl : UserControl
    {
        private static DocumentService _documentService;
        public TFSTimesheetReportControl()
        {
            InitializeComponent();
        }

        bool firstLoad = true;
        private void MyToolWindow_Loaded(object sender, RoutedEventArgs e)
        {

            if (firstLoad)
            {
                RefreshTreeView();
                firstLoad = false;
            }
        }

        internal static TeamFoundationServer GetCurrentTFSConnection()
        {
            
            try
            {
                var dte = Package.GetGlobalService(typeof(EnvDTE.DTE)) as EnvDTE.DTE;
                TeamFoundationServerExt ext = dte.GetObject("Microsoft.VisualStudio.TeamFoundation.TeamFoundationServerExt") as TeamFoundationServerExt;

                if (ext == null || ext.ActiveProjectContext == null || string.IsNullOrEmpty(ext.ActiveProjectContext.DomainUri))
                    return null;
                
                
                return TeamFoundationServerFactory.GetServer(ext.ActiveProjectContext.DomainUri, new UICredentialsProvider());
            }
            catch (Exception ex)
            {
                string exceptionDetails = string.Empty;

//#if DEBUG
                exceptionDetails = ex.Message;
//#endif

                MessageBox.Show(string.Format("An exception occurred while obtaining current TFS connection details. {0}", exceptionDetails));
                return null;
            }
    }

        internal static DocumentService GetDocumentService()
        {
            
            if (_documentService == null)
            {
                var dte = Package.GetGlobalService(typeof(EnvDTE.DTE)) as EnvDTE.DTE;
                _documentService = dte.GetObject("Microsoft.VisualStudio.TeamFoundation.WorkItemTracking.DocumentService") as DocumentService;
            }
            return _documentService;
        }

        private void RefreshTreeView()
        {
            treeView1.Items.Clear();


            // Only bother querying back items that actually contain timesheet data
            string queryText = @"SELECT [System.Id], [System.Title], [System.State] FROM WorkItems WHERE [Custom.Timesheets.TimesheetRawData] contains 'xml'";
            TimeSheetSummaryList summary = new TimeSheetSummaryList();

            #region Load Items from TFS
            TfsTeamProjectCollection tfsc = null;
            try
            {
                TeamFoundationServer tfs = GetCurrentTFSConnection();
                sbConnection.Content = (tfs == null ? "Disconnected (Connect via Team Explorer)" : "Connected");
                sbCollection.Visibility = (tfs == null ? Visibility.Hidden : System.Windows.Visibility.Visible);
                treeView1.Visibility = (tfs == null ? Visibility.Hidden : System.Windows.Visibility.Visible);

                if (tfs != null)
                {
                    try
                    {
                        // Open the connection to TFS
                        tfsc = tfs.TfsTeamProjectCollection;

                        // Sometimes when an exception is thrown the user session is terminated, 
                        // so we have to re-authenticate
                        if (!tfsc.HasAuthenticated)
                            tfsc.Authenticate();

                        sbCollection.Content = tfsc.Name;

                        // Get the work item service
                        var store = (WorkItemStore)tfsc.GetService(typeof(WorkItemStore));

                        // Execute the query
                        var wiCollection = store.Query(queryText);

                        // Iterate through all work items
                        foreach (WorkItem wi in wiCollection)
                        {
                            string timesheetData = wi.Fields["Custom.Timesheets.TimesheetRawData"].Value.ToString();
                            int id = wi.Id;
                            string project = wi.Project.Name;

                            summary.Add(new TimesheetSummary()
                            {
                                WorkItemID = id,
                                ProjectName = project,
                                Title = wi.Title,
                                Area = wi.AreaPath,
                                Iteration = wi.IterationPath,
                                WorkItemTimeSheet = TimeSheet.Deserialize(timesheetData)
                            });

                        }
                    }
                    catch (Exception ex)
                    {
                        string exceptionDetails = string.Empty;
                        string user = tfsc.AuthorizedIdentity.GetAttribute("DOMAIN", "");
                        //#if DEBUG
                        exceptionDetails = ex.Message;
                        //#endif
                        MessageBox.Show(String.Format("An exception occurred while querying work items. (UserDomain: {1}). {0}", exceptionDetails, user));
                        return;
                    }

                }
            }
            catch (Exception ex)
            {
                string exceptionDetails = string.Empty;
                string user = tfsc.AuthorizedIdentity.GetAttribute("DOMAIN", "");

#if DEBUG
                exceptionDetails = ex.Message;
#endif
                MessageBox.Show(String.Format("An exception occurred while attempting to load tfs work items. (UserDomain: {1}). {0}", exceptionDetails, user));
                return;
            }
            #endregion

            try
            {

                List<TimesheetSummaryItem> summaryItems = summary.GetFlatTimesheetEntries();

               // GroupingTreeViewItem myWorkThisWeek = new GroupingTreeViewItem(GroupingTreeViewItem.GroupBy.MyWorkThisWeek) { TimeSheetSummaryItems = summaryItems };
                

                //treeView1.Items.Add(myWorkThisWeek );
                treeView1.Items.Add(new GroupingTreeViewItem(GroupingTreeViewItem.GroupBy.Week) { TimeSheetSummaryItems = summaryItems });
                treeView1.Items.Add(new GroupingTreeViewItem(GroupingTreeViewItem.GroupBy.Project) { TimeSheetSummaryItems = summaryItems });
                treeView1.Items.Add(new GroupingTreeViewItem(GroupingTreeViewItem.GroupBy.Resource) { TimeSheetSummaryItems = summaryItems });
                //myWorkThisWeek.IsExpanded = true;

            }
            catch (Exception ex)
            {
                string exceptionDetails = string.Empty;

#if DEBUG
                exceptionDetails = ex.Message;
#endif
                MessageBox.Show(String.Format("An exception occurred while building display of timesheet data. {0}", exceptionDetails));
                return;
            }
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            RefreshTreeView();
        }
    }
}